package com.goods.business.service.imp;


import com.goods.business.mapper.InStockInfoMapper;
import com.goods.business.mapper.InStockMapper;
import com.goods.business.mapper.SupplierMapper;
import com.goods.business.service.InStockService;
import com.goods.common.model.business.InStock;
import com.goods.common.model.business.InStockInfo;
import com.goods.common.model.business.Product;
import com.goods.common.model.business.Supplier;
import com.goods.common.response.ActiveUser;
import com.goods.common.utils.ListPageUtils;
import com.goods.common.vo.business.InStockDetailVO;
import com.goods.common.vo.business.InStockVO;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.lang.reflect.InvocationHandler;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

@Service
public class InStockServiceImpl implements InStockService {
    @Resource
    private InStockMapper inStockMapper;
    @Resource
    private SupplierMapper supplierMapper;
    @Resource
    private InStockInfoMapper inStockInfoMapper;

    @Override
    public Map findInStockList(Map map) {
        Map map1 = new HashMap<>();
        Integer pageSize = Integer.parseInt((String) map.get("pageSize"));
        Integer pageNum = Integer.parseInt((String) map.get("pageNum"));
        Integer status = 0;
        if (!StringUtils.isEmpty(map.get("status").toString())) {
            status = Integer.parseInt((String) map.get("status"));
        }
        Integer type = null;
        if (!StringUtils.isEmpty(map.get("type"))) {
            status = Integer.parseInt((String) map.get("type"));
        }
        Integer inNum = null;
        if (!StringUtils.isEmpty(map.get("inNum"))) {
            inNum = Integer.parseInt((String) map.get("inNum"));
        }
        String endTime1 = null;
        if (!StringUtils.isEmpty(map.get("endTime"))) {
            endTime1 = map.get("endTime").toString();
        }
        String startTime1 = null;
        if (!StringUtils.isEmpty(map.get("startTime"))) {
            startTime1 = map.get("startTime").toString();
        }
        Date startTime = null;
        Date endTime = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            if (null == startTime1) {
                startTime = new Date();
            } else {
                startTime = sdf.parse(startTime1);
            }
            if (null == endTime1) {
                endTime = new Date();
            } else {
                endTime = sdf.parse(endTime1);
            }
            Date date = new Date();
            if (date.after(endTime) || date.before(startTime)) {
                List<InStockVO> list = inStockMapper.selectByAllAndStatus(status, type, inNum);
                List<InStockVO> page = ListPageUtils.page(list, pageSize, pageNum);
                map1.put("rows", page);
                map1.put("total", list.size());
                return map1;
            } else {
                List<InStockVO> list = inStockMapper.selectByAllAndStatus(status, type, inNum);
                List<InStockVO> page = ListPageUtils.page(list, pageSize, pageNum);
                map1.put("rows", page);
                map1.put("total", list.size());
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return map1;
    }

    @Override
    public boolean remove(Long id) {
        InStock inStock = this.getInStockId(id);
        inStock.setStatus(1);
        int i = inStockMapper.updateByPrimaryKey(inStock);
        if (i > 0) {
            return true;
        }
        return false;
    }

    @Override
    public boolean back(Long id) {
        InStock inStock = this.getInStockId(id);
        inStock.setStatus(0);
        int i = inStockMapper.updateByPrimaryKey(inStock);
        if (i > 0) {
            return true;
        }
        return false;
    }

    @Override
    public boolean delete(Long id) {
        InStock inStock = this.getInStockId(id);
        int i = inStockMapper.delete(inStock);
        if (i > 0) {
            return true;
        }
        return false;
    }

    @Override
    public Map detail(Long id, Integer pageNum) {
        List<InStockDetailVO> inStockDetailVO = inStockMapper.selectByIdAndSupId(id);
        if (CollectionUtils.isEmpty(inStockDetailVO)) {
            return null;
        }
        Map map = new HashMap<>();
        inStockDetailVO.stream().forEach(
                inStockDetailVO1 -> {
                    map.put("itemVOS", ListPageUtils.page(inStockDetailVO1.getItemVOS(), 3, pageNum));
                    map.put("total", inStockDetailVO1.getItemVOS().size());
                    map.put("supplierVO", inStockDetailVO1.getSupplierVO());
                    map.put("status", inStockDetailVO1.getStatus());
                }
        );
        return map;
    }

    @Transactional
    @Override
    public boolean addIntoStock(Map map) {
        String inNum = UUID.randomUUID().toString();
        String pNum = UUID.randomUUID().toString();
        Long supplierId = (Long) map.get("supplierId");
        String address = (String) map.get("address");
        String remark = (String) map.get("remark");
        Integer type = (Integer) map.get("type");
        String name = (String) map.get("name");
        if ("".equals(supplierId)) {
            String email = (String) map.get("email");
            String phone = (String) map.get("phone");
            Integer sort = (Integer) map.get("sort");
            String contact = (String) map.get("contact");
            Supplier supplier = new Supplier();
            supplier.setAddress(address);
            supplier.setEmail(email);
            supplier.setName(name);
            supplier.setPhone(phone);
            supplier.setSort(sort);
            supplier.setContact(contact);
            supplier.setCreateTime(new Date());
            supplier.setModifiedTime(new Date());
            supplierMapper.insert(supplier);
        }
        List<Product> products = (List<Product>) map.get("products");
        AtomicReference<Integer> i = new AtomicReference<>(0);
        if (!CollectionUtils.isEmpty(products)) {
            products.stream().forEach(
                    o -> {
                        InStockInfo inStockInfo = new InStockInfo();
                        Integer pNumber = Integer.parseInt(o.getPNum());
                        inStockInfo.setInNum(inNum);
                        inStockInfo.setPNum(pNum);
                        i.updateAndGet(v -> Math.toIntExact(v + pNumber));
                        inStockInfo.setProductNumber(pNumber);
                        inStockInfo.setCreateTime(new Date());
                        inStockInfo.setModifiedTime(new Date());
                        inStockInfoMapper.insert(inStockInfo);
                    }
            );
        }
        InStock inStock = new InStock();
        inStock.setType(type);
        inStock.setInNum(inNum);
        inStock.setCreateTime(new Date());
        inStock.setModified(new Date());
        inStock.setRemark(remark);
        inStock.setStatus(2);
        if (!StringUtils.isEmpty(name)) {
            Supplier supplier = supplierMapper.selectByNameOrAddress(name,address);
            inStock.setSupplierId(supplier.getId());
        } else {
            inStock.setSupplierId(supplierId);
        }
        ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();
        String nickname = activeUser.getUser().getNickname();
        inStock.setOperator(nickname);
        inStockMapper.insert(inStock);
        return true;
    }

    private InStock getInStockId(Long id) {
        InStock inStock = inStockMapper.selectByPrimaryKey(id);
        return inStock;
    }
}